<?php

declare(strict_types=1);

namespace app\admin\controller\auth;

use think\Request;
use sheep\controller\Backend;
use app\admin\model\auth\Role as RoleModel;
use app\admin\model\auth\Access as AccessModel;
use sheep\exception\SheepException;
use sheep\library\Tree;
use think\facade\Db;


class Role extends Backend
{
    protected function initialize()
    {
        $this->model = new RoleModel;
        $this->accessModel = new AccessModel;
    }
    /**
     * 获取角色列表
     *
     * @return void
     */
    public function list()
    {
        $admin = $this->auth()->user();

        $data = (new Tree($this->model))->getChildren($admin->role_id);

        return success('', $data);
    }

    /**
     * 添加角色
     */
    public function add(Request $request)
    {
        $params = $request->only(['parent_id', 'name', 'code', 'description', 'status', 'rules']);

        $this->svalidate($params, ".add");

        $this->isRightAccess($params['parent_id'], $params['rules']);

        $data = Db::transaction(function () use ($params) {
            return $this->model->save($params);
        });

        // TODO 添加权限角色组缓存映射

        return success('添加成功', $data);
    }

    /**
     * 角色详情
     */
    public function detail($id)
    {
        $admin = $this->auth()->user();

        $this->isRightRole($id);

        $role = $this->model->findOrFail($id);

        return success('', $role);
    }

    /**
     * 更新角色
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function edit(Request $request, $id)
    {
        $params = $request->only(['parent_id', 'name', 'code', 'description', 'status', 'rules']);

        $params['id'] = $id;

        $this->svalidate($params);

        $this->isRightRole($id);

        $this->isRightAccess($params['parent_id'], $params['rules']);

        Db::transaction(function () use ($id, $params) {
            $this->model->findOrFail($id)->save($params);
        });

        return success('保存成功');
    }

    /**
     * 删除角色组
     *
     * @param  $id
     * @return \think\Response
     */
    public function delete($id)
    {
        $this->isRightRole($id);

        $role = $this->model->findOrFail($id);

        if ($this->model->where('parent_id', $role->id)->count()) {
            throw new SheepException('请先删除下级角色组');
        }
        if (\app\admin\model\auth\Admin::where('role_id', $role->id)->count()) {
            throw new SheepException('请先移除对应管理员');
        }

        $role->delete();

        return success('删除成功');
    }
    /**
     * 选择角色组
     *
     * @return \think\Response
     */
    public function select()
    {
        $admin = $this->auth()->user();

        $data = (new Tree(function () {
            return $this->model->normal()->field("id, name, status");
        }))->getChildren($admin->role_id);

        return success('', $data);
    }

    /**
     * 角色组过滤检查,不可操作自己的角色组
     */
    private function isRightRole($id)
    {
        $admin = $this->auth()->user();

        $childRoleIds = $this->auth()->getChildRoleIds(false);

        if (!in_array($id, $childRoleIds) || $id == $admin->role_id) {
            throw new SheepException('无权限操作该角色组');
        }

        return true;
    }

    /**
     * 权限节点过滤检查,不可选择无权限的上级角色组,不可分配无权限的权限节点
     */
    private function isRightAccess($parentId, $rules)
    {
        $canSelectRoleIds = $this->auth()->getChildRoleIds(true);

        if (!in_array($parentId, $canSelectRoleIds)) {
            throw new SheepException('请选择正确的上级');
        }

        $parentRules = $this->auth()->getRulesByRole($parentId);

        if (array_diff($rules, $parentRules)) {
            throw new SheepException('请选择正确的权限节点');
        }

        return true;
    }
}
